package com.gobang.controller;

import com.gobang.common.constant.BusinessErrorCode;
import com.gobang.common.exception.BusinessException;
import com.gobang.domain.dto.PageRequest;
import com.gobang.domain.vo.PageData;
import com.gobang.domain.vo.Result;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Hello World 测试控制器
 * 用于验证后端服务是否正常运行
 * 演示统一返回格式和异常处理的使用
 * 演示 SLF4J 日志的使用
 * 
 * @author Gobang Team
 */
@Slf4j
@RestController
public class HelloController {

    /**
     * Hello World 接口（使用统一返回格式）
     * 演示 INFO 级别日志
     * 
     * @return 欢迎信息
     */
    @GetMapping("/hello")
    public Result<String> hello() {
        log.info("收到 Hello 请求");
        return Result.success("欢迎使用五子棋在线对战平台后端服务！");
    }

    /**
     * 健康检查接口
     * 演示 DEBUG 级别日志
     * 
     * @return 服务状态
     */
    @GetMapping("/health")
    public Result<Map<String, String>> health() {
        log.debug("执行健康检查");
        Map<String, String> data = new HashMap<>();
        data.put("status", "UP");
        data.put("service", "Gobang Backend Service");
        data.put("version", "1.0.0");
        log.debug("健康检查完成，服务状态：{}", data.get("status"));
        return Result.success("服务运行正常", data);
    }

    /**
     * 测试成功响应（带数据）
     * 演示带参数的日志输出
     * 
     * @param name 用户名
     * @return 问候信息
     */
    @GetMapping("/test/success")
    public Result<Map<String, Object>> testSuccess(@RequestParam(defaultValue = "Guest") String name) {
        log.info("处理成功响应请求，用户名：{}", name);
        Map<String, Object> data = new HashMap<>();
        data.put("greeting", "你好，" + name + "！");
        data.put("message", "这是一个成功响应的示例");
        log.debug("构造响应数据：{}", data);
        return Result.success(data);
    }

    /**
     * 测试业务异常
     * 演示 WARN 级别日志
     * 
     * @param throwError 是否抛出异常
     * @return 响应结果
     */
    @GetMapping("/test/error")
    public Result<String> testError(@RequestParam(defaultValue = "false") Boolean throwError) {
        log.info("测试业务异常接口被调用，throwError={}", throwError);
        if (throwError) {
            log.warn("准备抛出业务异常：用户不存在");
            // 演示：抛出业务异常（会被全局异常处理器捕获）
            throw new BusinessException(BusinessErrorCode.USER_NOT_FOUND);
        }
        return Result.success("没有错误发生");
    }

    /**
     * 测试参数校验异常
     * 
     * @param age 年龄（必须大于0）
     * @return 响应结果
     */
    @GetMapping("/test/validation")
    public Result<String> testValidation(@RequestParam Integer age) {
        if (age <= 0) {
            throw new BusinessException(BusinessErrorCode.PARAM_INVALID, "年龄必须大于0");
        }
        return Result.success("参数校验通过，年龄：" + age);
    }

    /**
     * 测试自定义错误码
     * 
     * @return 响应结果
     */
    @GetMapping("/test/custom-error")
    public Result<String> testCustomError() {
        throw new BusinessException(40001, "这是一个自定义错误码的示例");
    }

    /**
     * 测试系统异常（空指针）
     * 演示 ERROR 级别日志
     * 
     * @param trigger 是否触发异常
     * @return 响应结果
     */
    @GetMapping("/test/system-error")
    public Result<String> testSystemError(@RequestParam(defaultValue = "false") Boolean trigger) {
        log.info("测试系统异常接口被调用，trigger={}", trigger);
        if (trigger) {
            log.error("即将触发系统异常（用于测试）");
            // 演示：空指针异常（会被全局异常处理器捕获）
            // 此处故意触发空指针异常，用于测试全局异常处理器
            @SuppressWarnings("null")
            String str = null;
            str.length();
        }
        return Result.success("没有系统错误发生");
    }

    /**
     * 测试分页响应（使用单独参数）
     * 
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @return 分页结果
     */
    @GetMapping("/test/page")
    public Result<PageData<Map<String, Object>>> testPage(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize) {
        
        // 模拟数据总数
        long total = 50L;
        
        // 模拟数据列表
        List<Map<String, Object>> list = new ArrayList<>();
        int start = (pageNum - 1) * pageSize + 1;
        int end = Math.min(pageNum * pageSize, (int) total);
        
        for (int i = start; i <= end; i++) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", i);
            item.put("name", "数据项" + i);
            item.put("description", "这是第" + i + "条测试数据");
            list.add(item);
        }
        
        // 创建分页数据
        PageData<Map<String, Object>> pageData = PageData.of(pageNum, pageSize, total, list);
        
        return Result.success(pageData);
    }

    /**
     * 测试分页响应（使用PageRequest对象）
     * 推荐使用此方式，参数更规范
     * 
     * @param pageRequest 分页请求参数
     * @return 分页结果
     */
    @GetMapping("/test/page-request")
    public Result<PageData<Map<String, Object>>> testPageWithRequest(@Valid PageRequest pageRequest) {
        
        // 模拟数据总数
        long total = 50L;
        
        // 模拟数据列表
        List<Map<String, Object>> list = new ArrayList<>();
        int start = (int) pageRequest.getOffset() + 1;
        int end = Math.min(pageRequest.getPageNum() * pageRequest.getPageSize(), (int) total);
        
        for (int i = start; i <= end; i++) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", i);
            item.put("name", "数据项" + i);
            item.put("description", "这是第" + i + "条测试数据");
            list.add(item);
        }
        
        // 创建分页数据
        PageData<Map<String, Object>> pageData = PageData.of(
            pageRequest.getPageNum(),
            pageRequest.getPageSize(),
            total,
            list
        );
        
        return Result.success(pageData);
    }

    /**
     * 测试分页响应（带排序）
     * 
     * @param pageRequest 分页请求参数
     * @return 分页结果
     */
    @GetMapping("/test/page-order")
    public Result<PageData<Map<String, Object>>> testPageWithOrder(@Valid PageRequest pageRequest) {
        
        // 模拟数据列表
        List<Map<String, Object>> list = new ArrayList<>();
        for (int i = 1; i <= 20; i++) {
            Map<String, Object> item = new HashMap<>();
            item.put("id", i);
            item.put("name", "数据项" + i);
            item.put("score", (int) (Math.random() * 100));
            item.put("createdAt", "2025-10-" + String.format("%02d", i));
            list.add(item);
        }
        
        // 根据排序字段排序
        if (pageRequest.hasOrder()) {
            String orderBy = pageRequest.getOrderBy();
            boolean isAsc = pageRequest.isAsc();
            
            list.sort((a, b) -> {
                Object aValue = a.get(orderBy);
                Object bValue = b.get(orderBy);
                
                if (aValue instanceof Comparable && bValue instanceof Comparable) {
                    @SuppressWarnings("unchecked")
                    Comparable<Object> aComp = (Comparable<Object>) aValue;
                    int result = aComp.compareTo(bValue);
                    return isAsc ? result : -result;
                }
                return 0;
            });
        }
        
        // 分页
        long total = list.size();
        int start = (int) pageRequest.getOffset();
        int end = Math.min(start + pageRequest.getPageSize(), list.size());
        List<Map<String, Object>> pageList = list.subList(start, end);
        
        // 创建分页数据
        PageData<Map<String, Object>> pageData = PageData.of(
            pageRequest.getPageNum(),
            pageRequest.getPageSize(),
            total,
            pageList
        );
        
        return Result.success(pageData);
    }

    /**
     * 测试空分页响应
     * 
     * @return 空分页结果
     */
    @GetMapping("/test/page-empty")
    public Result<PageData<String>> testPageEmpty() {
        PageData<String> pageData = PageData.empty();
        return Result.success("暂无数据", pageData);
    }

}

